#include "uart0.h"
#include "CH58x_common.h"
#include "stdbool.h"
#include "stdint.h"
#include "app_flag.h"
#include "flash_board.h"
#include "flash.h"
#include "tim.h"
#include "iwdg.h"
#include "basic.h"
#include "uartapp.h"
uint8_t DestMac[6];
uint8_t SourceMac[6];
static uint8_t Uart0RecvBuff[UART_RECV_MAX_LEN]={0};
static uint16_t Uart0RecvIndex={0};
static uint8_t Uart0RecvOverFg=0;

uint8_t Device_Satus=0;
void Uart0SetSendEnablePinLevel(bool PinLevel);


/*
crc�ۼӼ���
*/
uint8_t calculateChecksum(uint8_t *data, uint8_t length)
{
    uint8_t sum = 0;
    for (uint8_t i = 0; i < length; i++)
    {
        sum += data[i];
    }
    return sum & 0xFF;
}


/*********************************************************************
 * @fn      USARTx_CFG
 *
 * @brief   Initializes the USART0  peripheral.
 *
 * @return  none
 */
void USART0_Init(uint32_t BaudRate)
{
  GPIOA_ModeCfg(UART0_ENABLE_PIN, GPIO_ModeOut_PP_20mA);
  GPIOPinRemap(ENABLE, RB_PIN_UART0);
  GPIOB_SetBits(UART0_TX_PIN);
  GPIOA_ModeCfg(UART0_RX_PIN, GPIO_ModeIN_PU);
  GPIOA_ModeCfg(UART0_TX_PIN, GPIO_ModeOut_PP_20mA);
  UART0_DefInit();
  UART0_BaudRateCfg(BaudRate);
  UART0_ByteTrigCfg(UART_7BYTE_TRIG);
  UART0_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT);
  PFIC_EnableIRQ(UART0_IRQn);
  Uart0SetSendEnablePinLevel(false);
}




/*********************************************************************
 * @fn      UART1_IRQHandler
 *
 * @brief   UART0�ж�
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE

void UART0_IRQHandler(void)
{
    volatile uint8_t i;
    switch (UART0_GetITFlag())
    {
        case UART_II_LINE_STAT:
        {
            UART0_GetLinSTA(); // @suppress("Statement has no effect")
        }
        break;

        case UART_II_RECV_RDY:
        {
            uint8_t WirelessUartRxData = UART0_RecvByte();
            if(Uart0RecvIndex<600)
            {
                Uart0RecvBuff[Uart0RecvIndex]=WirelessUartRxData;
                Uart0RecvIndex++;
            }   
            else
                Uart0RecvIndex=0;
        }
        break;

        case UART_II_RECV_TOUT:
        {
             uint16_t TmpDataCount = 0;
             uint8_t TmpDataBuff[600] = {0};
             TmpDataCount = UART0_RecvString(TmpDataBuff);
            //  PRINT(" more %02x \r\n",TmpDataCount);
            // if(Uart0RecvIndex<(UART_RECV_MAX_LEN))
            {
                // uint16_t i=0;
                //   PRINT(" more %02x \r\n",TmpDataCount);
                // for(i=0;i<TmpDataCount;i++)
                //     printf("%02x \r\n",TmpDataBuff[i]);
                
                memcpy(&Uart0RecvBuff[Uart0RecvIndex],TmpDataBuff,TmpDataCount);
                Uart0RecvIndex=Uart0RecvIndex+TmpDataCount;
                // Set_RecvTimeCount();
                 Set_Recv_Over(true);
                // UartRecvBuff[UartRecvIndex]=WirelessUartRxData;
            }
            // else
            //     Uart0RecvIndex=0;
        }
        break;
    }
}

void Uart0_SendDate(uint8_t *iPdate,uint16_t Len)
{
    uint8_t i=0;
    uint8_t Index=DestMac[5];
    Uart0SetSendEnablePinLevel(true);
    FEED_IWDG();
    PRINT("senddate:");
    for(i=0;i<Len;i++)
        PRINT("%02x ",iPdate[i]);
    PRINT("\r\n");
    UART0_SendString(iPdate, Len);
    while ((R8_UART0_LSR & RB_LSR_TX_ALL_EMP) == 0)
    {
        __nop();
    }
    Uart0SetSendEnablePinLevel(false);
}

void UartDelayMs(uint16_t Ms)
{
  DelayMs(Ms);
}

static void UART0SetSendEnablePinHighLevel(void)
{
  GPIOA_SetBits(UART0_ENABLE_PIN);
}

static void UART0SetSendEnablePinLowLevel(void)
{
  GPIOA_ResetBits(UART0_ENABLE_PIN);
}


void Uart0SetSendEnablePinLevel(bool PinLevel)
{
  (PinLevel == true) ? UART0SetSendEnablePinHighLevel() : UART0SetSendEnablePinLowLevel();
  UartDelayMs(UART_WAIT_DEVICE_READY_TIME);
}

void Set_Recv_Over(uint8_t Status)
{
    Uart0RecvOverFg=Status;
}

uint8_t Get_Recv_Over(void)
{
    return Uart0RecvOverFg;
}

uint16_t Get_Uart_Date_Len(void)
{
    return Uart0RecvIndex;
}

void Clear_Uart_Len(void)
{ 
     memset(Uart0RecvBuff,0,Uart0RecvIndex);
     Uart0RecvIndex=0;
}

void Get_Uart_Date(uint8_t *oPdate,uint16_t size)
{
    memcpy(oPdate,Uart0RecvBuff,size);
}


void AnswerHandleAddr(void)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x06;
    SendDate[4]=READELESETADDR;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    memcpy(&SendDate[17],DestMac,6);
    SendDate[23]=calculateChecksum(SendDate,23);
    Uart0_SendDate(SendDate,24);  
}

void AnswerSetEleOpen(uint8_t Result)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=SETELEOPEN;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=Result;
    SendDate[18]=calculateChecksum(SendDate,18);
    PRINT("answer set ele \r\n");
    Uart0_SendDate(SendDate,19);  
}

void AnswerGetOtaResult(uint8_t Status)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=GETOTARESULT;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=Status;
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19); 
    if(Status==DEVICE_OTA_RUNNING)
    {
        BackUp_FirmWare();
        PRINT("jump iap\r\n");
        DelayMs(2000);
        jumpToIap();
    }
}

void AnswerRecvOtaDate(uint8_t Status)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=SETELEOTA;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=Status;
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19);  
}

void AnswerSetEmergency(uint8_t Status)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=SETELEEMERGENCYMOD;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=Status;
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19);  
}


/*��������״̬
1��ota���ճɹ�   2��ota����ʧ�� 3��ota������ 4���̼��汾����   5.������
*/
void Set_Device_Status(uint8_t Status)
{
    Device_Satus=Status;
}

/*��ѯ����״̬
1��ota���ճɹ�   2��ota����ʧ�� 3��ota������ 4���̼��汾����   5.������
*/
uint8_t Get_Device_Status(void)
{
    return Device_Satus;
}

void AnswerVersion(void)
{
    uint8_t SendDate[50]={0};
    const char *pSubscribeTopic = (const char *)Version;
    uint8_t VersionDate[30];
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x1E;
    SendDate[4]=GETELEGETVER;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    strcpy(VersionDate, pSubscribeTopic);
    memcpy(&SendDate[17],VersionDate,30);
    SendDate[47]=calculateChecksum(SendDate,47);
    Uart0_SendDate(SendDate,48);  
}

void AnswerHandleSelfTest(void)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=SETELESELFTEST;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=1;
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19);  
}

void AnswerHandleSetFireMode(void)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=SETFIREMODE;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=1;
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19);  
}

void AnswerHandleGetFireStatus(void)
{
    uint8_t SendDate[30]={0};
    SendDate[0]=Header1;
    SendDate[1]=Header2;
    SendDate[2]=0x00;
    SendDate[3]=0x01;
    SendDate[4]=GETFIRESTATUS;
    memcpy(&SendDate[5],DestMac,6);
    memcpy(&SendDate[11],SourceMac,6);
    SendDate[17]=Get_Fire_Status();
    SendDate[18]=calculateChecksum(SendDate,18);
    Uart0_SendDate(SendDate,19);  
}


